<template>
  <div>
    <div class="flex justify-between mb-5">
      <p class="text-base">已保存配置列表</p>
      <div class="flex gap-2">
        <ElButton type="primary" size="small" @click="exportConfig">导出</ElButton>
        <ElButton type="primary" size="small" @click="importConfig">导入</ElButton>
        <ElButton type="primary" size="small" @click="uploadConfig">上传</ElButton>
        <ElButton type="primary" size="small" @click="downloadConfig">下载</ElButton>
        <ElButton type="danger" size="small" @click="reset">重置配置</ElButton>
      </div>
    </div>

    <!-- 添加隐藏的文件输入框 -->
    <input
      type="file"
      ref="fileInput"
      style="display: none"
      accept=".json"
      @change="handleFileImport"
    />

    <ElCard v-for="c in configurations" :class="{ active: c.id == activeConfigurationId }" class="mb-3" :shadow="'hover'"
      @click="select(c.id)">
      <div class="flex justify-between items-center cursor-pointer">
        <p class="text-sm">{{ c.name }}</p>
        <el-icon v-if="configurations && configurations.length > 1" @click.stop="remove(c.id)">
          <CircleCloseFilled />
        </el-icon>
      </div>
    </ElCard>
  </div>
</template>

<script setup>
import { getCurrentInstance, ref, computed, watch, nextTick } from 'vue';
import ConfigStorage from '@/utils/configStorage';
import { cloneDeep } from 'lodash';
import { ElMessage } from 'element-plus';
import { ConfigSyncService } from '@/services/configSyncService';

const { proxy } = getCurrentInstance()
const fileInput = ref(null)

const props = defineProps({
  activeIndex: {
    type: String,
    default: '1'
  },
  configurations: Array
})

const emits = defineEmits(['removed', 'selected', 'reset', 'update:activeIndex'])

const activeConfigurationId = computed({
  get() {
    return props.activeIndex
  },
  set(val) {
    emits('update:activeIndex', val)
  }
})

const remove = async (id) => {
  try {
    await proxy.$messageBox.confirm('确定删除吗？', '提示', { type: 'warning' })
    new ConfigStorage().remove(id)
    proxy.$message.success('删除成功！')
    // 如果删除的配置正在被使用，则自动选择第一个
    if (activeConfigurationId.value == id) {
      activeConfigurationId.value = props.configurations[0].id
    }
    emits('removed')
  } catch (error) {

  }
}

const reset = async () => {
  try {
    await proxy.$messageBox.confirm('确定重置吗？', '提示', { type: 'warning' })

    const configStorage = new ConfigStorage()
    configStorage.clear()

    if (activeConfigurationId.value == '1') {
      proxy.$message.success('重置成功')
      emits('reset')
    } else {
      emits('reset')
      nextTick(()=>{
        const c = props.configurations.find(p => p.id == '1')
        activeConfigurationId.value = '1'
        emits('selected', cloneDeep(c))
        proxy.$message.success('重置成功')
      })
    }
  } catch (error) {

  }
}

const select = async (id) => {
  try {
    await proxy.$messageBox.confirm('确定加载吗？注意未保存的参数将会丢失！', '提示', { type: 'warning' })
    activeConfigurationId.value = id
  } catch (error) {
  }
}

watch(() => props.activeIndex, async (val) => {
  const c = props.configurations.find(p => p.id == val)
  emits('selected', cloneDeep(c))
})

// 导出配置
const exportConfig = () => {
  const configStorage = new ConfigStorage();
  const configs = configStorage.getConfigurations();

  const dataStr = JSON.stringify(configs, null, 2);
  const blob = new Blob([dataStr], { type: 'application/json' });
  const url = URL.createObjectURL(blob);

  const link = document.createElement('a');
  link.href = url;
  link.download = `口算题配置_${new Date().toISOString().split('T')[0]}.json`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

// 触发文件选择
const importConfig = () => {
  fileInput.value.click();
}

// 处理文件导入
const handleFileImport = async (event) => {
  const file = event.target.files[0];
  if (!file) return;

  try {
    await proxy.$messageBox.confirm('导入将覆盖现有配置，确定继续吗？', '提示', { type: 'warning' });

    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const configs = JSON.parse(e.target.result);

        // 验证导入的配置格式
        if (!Array.isArray(configs)) {
          throw new Error('配置格式不正确');
        }

        // 验证每个配置项的必要字段
        configs.forEach(config => {
          if (!config.id || !config.name || !config.data) {
            throw new Error('配置数据格式不完整');
          }
        });

        // 确保至少有一个配置
        if (configs.length === 0) {
          throw new Error('配置文件为空');
        }

        // 确保第一个配置的 id 为 '1'
        const defaultConfig = configs.find(c => c.id === '1');
        if (!defaultConfig) {
          configs[0].id = '1';
        }

        const configStorage = new ConfigStorage();
        configStorage.clear();
        // 直接设置配置
        configStorage.setConfigurations(configs);

        emits('reset');
        ElMessage.success('配置导入成功');
      } catch (error) {
        console.error('导入错误：', error);
        ElMessage.error('配置导入失败：' + error.message);
      }
    };

    reader.readAsText(file);
  } catch (error) {
    // 用户取消导入
  } finally {
    // 清除文件输入，允许重复导入相同文件
    event.target.value = '';
  }
}

// 上传配置
const uploadConfig = async () => {
  try {
    const configSyncService = new ConfigSyncService();
    await configSyncService.uploadConfigurations();
    proxy.$message.success('配置上传成功');
  } catch (error) {
    proxy.$message.error('配置上传失败');
  }
}

// 下载配置
const downloadConfig = async () => {
  try {
    const configSyncService = new ConfigSyncService();
    const updated = await configSyncService.downloadConfigurations();
    if (updated) {
      emits('reset');
      proxy.$message.success('配置下载成功');
    } else {
      proxy.$message.warning('远程没有可用的配置');
    }
  } catch (error) {
    proxy.$message.error('配置下载失败');
  }
}

</script>

<style lang="scss" scoped>
.active {
  @apply bg-sky-100;
}

i{
  @apply text-xl text-sky-600;
}
</style>
